package cn.iocoder.yudao.module.system.service.tiktok.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.iocoder.yudao.module.system.config.TiktokProperties;
import cn.iocoder.yudao.module.system.dal.dataobject.tiktok.TiktokUser;
import cn.iocoder.yudao.module.system.dal.dto.tiktok.TiktokUserDto;
import cn.iocoder.yudao.module.system.service.tiktok.TiktokService;
import cn.iocoder.yudao.module.system.service.tiktok.TiktokUserService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.Instant;
import java.util.Optional;

@Slf4j
@Service
public class TiktokServiceImpl implements TiktokService {
    @Resource
    private TiktokUserService tiktokUserService;

    @Resource
    private TiktokProperties tiktokProperties;

    @Override
    public void getUserAuth(String state, String code, String scopes, String error, String errorDescription) {
        log.info("state:{}", state);
        log.info("code:{}", code);
        log.info("scopes:{}", scopes);
        log.info("error:{}", error);
        log.info("errorDescription:{}", errorDescription);
        //获取用户accessToken
        String tiktokUserAccessTokenBase = tiktokProperties.getTiktokUserAccessTokenBase();
        HttpResponse accessTokenResponse = HttpUtil.createPost(tiktokUserAccessTokenBase)
                .header("Content-Type", "application/x-www-form-urlencoded")
                .header("Accept", "application/x-www-form-urlencoded")
                .form("client_key", tiktokProperties.getClientKey())
                .form("client_secret", tiktokProperties.getClientSecret())
                .form("code", code)
                .form("grant_type", "authorization_code")
                .form("redirect_uri", tiktokProperties.getRedirectUri())
                .execute();
        String body = accessTokenResponse.body();
        log.info("accessTokenBody:{}", body);
        //todo 需要判断异常的情况
        TiktokUserDto tiktokUser = JSONObject.parseObject(body, TiktokUserDto.class);

        //获取用户基础信息
        HttpResponse response = HttpUtil.createGet(tiktokProperties.getTiktokUserInfoBase())
                .header("Authorization", "Bearer " + tiktokUser.getAccessToken())
                .header("Accept", "application/x-www-form-urlencoded")
                .execute();

        //调用接口获取用户信息
        String userBody = response.body();
        log.info("userBody:{}", userBody);
        JSONObject userInfoBody = JSONObject.parseObject(userBody);
        getUserInfo(userInfoBody, tiktokUser);
        TiktokUser param = new TiktokUser();
        BeanUtil.copyProperties(tiktokUser, param, false);
        if (StringUtils.isNotBlank(tiktokUser.getOpenId())) {
            //查询是否存在旧数据
            TiktokUser one = tiktokUserService.getOne(Wrappers.lambdaQuery(TiktokUser.class)
                    .eq(TiktokUser::getOpenId, tiktokUser.getOpenId())
                    .orderByDesc(TiktokUser::getId)
                    .last("limit 1"));
            Optional.ofNullable(one).ifPresent(e -> {
                param.setId(e.getId()).setUpdateTime(Instant.now());
            });
        }
        Instant now = Instant.now();
        Instant accessTokenExpires = now.plus(Duration.ofSeconds(tiktokUser.getExpiresInLong()));
        Instant refreshAccessTokenExpires = now.plus(Duration.ofSeconds(tiktokUser.getRefreshExpiresInLong()));
        param.setExpiresIn(accessTokenExpires).setRefreshExpiresIn(refreshAccessTokenExpires);
        tiktokUserService.saveOrUpdate(param);
    }

    private void getUserInfo(JSONObject userInfoBody, TiktokUserDto tiktokUser) {
        JSONObject data = userInfoBody.getJSONObject("data");
        JSONObject user = data.getJSONObject("user");
        TiktokUserDto userResp = JSONObject.parseObject(user.toJSONString(), TiktokUserDto.class);
        CopyOptions copyOptions = new CopyOptions().setIgnoreNullValue(true);
        BeanUtil.copyProperties(userResp, tiktokUser, copyOptions);
    }
}